#ifndef ZIP_AC_DEC_DIRECT_H_INCLUDED
#define ZIP_AC_DEC_DIRECT_H_INCLUDED

#ifdef __cplusplus
extern "C" {
#endif

// 得到空调状态支持情况，支持的模式，风向，每个模式支持的温度和风速范围
// data遥控器数据首地址, data_len遥控器数据总长度
// mode_flags 长度至少包含5个unsigned short元素，0-4一共5个unsigned short分别对应制冷，制热，自动，送风，除湿模式的信息
// mode_flags的每个unsigned short包含信息的规则为：
// 为0则表示不支持该模式，从低到高0-3bit存储该模式支持的温度最小值与16的差（0000对应最小值16度,
// 0010 对应温度最小值为18度)，从低到高4-7bit存储该模式支持的温度最大值与16的差（1110对应最大值30度）
// 最小最大值都为0则表示不支持温度调节
// 从低到高8-11bit每bit分别对应风速自动，低，中，高，为1则表示支持该风速，为0则表示不支持(1111表示4种风速都支持，1000表示只支持自动风速)
// wind_direct_flag 返回遥控器方向支持情况，请结合使用场景（1 开机后同步所有状态  2 按风向键或响应更改风向指令 3 响应温度，模式，风速控制指令）参考以下说明
//
// 返回0表示不支持调节风向
// 场景1,2,3均无需处理wind_direct_flag（get_ac_state_pulse接口wind_direct请传0,wind_direct_flag可以传NULL）
//
// 返回1表示风向只有一组码值，发射这组码值则风向在扫风和固定风向之间来回切换
// 场景1无需处理wind_direct_flag（同步其他状态时get_ac_state_pulse接口wind_direct请传1,wind_direct_flag可以传NULL）
// 场景2需处理wind_direct_flag（get_ac_state_pulse接口wind_direct请传1,wind_direct_flag不能为NULL，指向的值设置为1，无须判断返回值）
// 场景3无需处理wind_direct_flag（同步其他状态时get_ac_state_pulse接口wind_direct请传1,wind_direct_flag可以传NULL）
//
// 返回2表示扫风和固定风向有2组不同的码
// 场景1需处理wind_direct_flag（同步所有状态时get_ac_state_pulse接口wind_direct传0获取扫风的码，传1获取固定风向的码,
// wind_direct_flag不能为NULL，指向的值设置为0，调用get_ac_state_pulse返回后需要判断wind_direct_flag指向的值是否被更改为1，
// 如果为1则需要再次调用get_ac_state_pulse其他参数保持不变，wind_direct_flag指向的值设置为1，再次获取红外码，这两组码之间建议间隔800ms左右进行发送）
// 场景2需处理wind_direct_flag（get_ac_state_pulse接口wind_direct传0获取扫风的码，传1获取固定风向的码,wind_direct_flag不能为NULL，指向的值设置为1，无须判断返回值）
// 场景3无须处理wind_direct_flag（同步其他状态时get_ac_state_pulse接口wind_direct传0获取扫风的码，传1获取固定风向的码,wind_direct_flag可以传NULL）
//
// 返回0成功，-1 data指向的数据不合法
int get_ac_info(const unsigned char *data, unsigned short data_len,
		unsigned short *mode_flags, unsigned char *wind_direct_flag);

// 得到开机状态下的指定状态的红外脉冲数据
// data遥控器数据首地址, data_len遥控器数据总长度,
// mode 模式[0-4对应制冷，制热，自动，送风，除湿], temperature 温度[16-30]，
// wind_speed 风速[0-3对应自动，低，中，高]，wind_direct 风向[0 扫风，1 停止扫风]
// wind_direct_flag此参数既输入又输出，输入为0时获取的为同步所有状态默认的码（对于大多数空调只需要发这一个码所有状态都能一次同步，
// 但对于少数空调来说风向是单独的码，此时wind_direct_flag参数会返回1,
// 表示还需要再次获取同步风向的码（调用方在获取到码发送后需要再次调用该方法，参数唯一需要改变的是wind_direct_flag输入1，
// 此时返回同步风向的码进行发送，同时该次调用wind_direct_flag会返回0）
// frequency返回频率比如38000，
// out 调用方准备好的返回高低电平缓冲区（单位：脉冲个数），
// out_max_num out允许存放的最大元素个数(out指向的可用内存空间/sizeof(unsigned short))，
// ret_num 编码完成后在out 内存空间中实际写了多少个unsigned short元素，
// frame_count 通过out返回的高低电平数组（一帧）需要重复的次数
//
// 返回值 0 成功，-1 data指向的数据不合法，-2 mode 参数取值不在[0-4]范围内， -3 遥控器不支持mode参数指定的模式
// 注意： temperature和win_speed参数会自动使用最近的有效值，比如temperature传入15则会当16处理，传入31则会当30处理
// wind_speed传入4会当3处理
int get_ac_state_pulse(const unsigned char *data, unsigned short data_len,
		unsigned char mode, unsigned char temperature, unsigned char wind_speed,
		unsigned char wind_direct, unsigned char *wind_direct_flag,
		unsigned short *frequency, unsigned short *out,
		unsigned short out_max_num, unsigned short *ret_num,
		unsigned char *frame_count);

// 得到开关机红外脉冲数据, power 开关机[0 开机， 1 关机]
// 其他参数说明请参考get_ac_state_pulse
//
int get_ac_power_pulse(const unsigned char *data, unsigned short data_len,
		unsigned char power, unsigned short *frequency, unsigned short *out,
		unsigned short out_max_num, unsigned short *ret_num,
		unsigned char *frame_count);

// 根据学习到的红外高低电平宽度数组(单位us)搜索码库
// data 索引数据首地址, data_len索引数据总长度
// pattern 学习到的红外高低电平宽度数组(单位us), pattern_num pattern缓冲区内高低电平个数
// device_type 搜索的遥控器设备类型，5 空调， 8 风扇
// remote_num 返回根据传入的电平搜索到的遥控码总套数，remote_handle 返回第一套遥控码的句柄（用来获取下一套，不需要取下一套则传NULL）
// remote_id 第一套遥控码的id,不需要则传NULL， remote_data_offset 返回第一套遥控码在数据文件中的偏移量
// remote_data_len返回第一套遥控码数据长度
//
// 返回值 0 成功， -1 索引数据错误， -2 红外数据无法识别，-3 索引文件找不到匹配的遥控码, -4 device_type参数值不正确
int search_remote(const unsigned char *data, unsigned short data_len,
		int *pattern, int pattern_num, unsigned char device_type,
		unsigned short *remote_num, unsigned short *remote_handle,
		unsigned short *remote_id, int *remote_data_offset,
		unsigned short *remote_data_len);

// 根据当前遥控器的句柄获取下一套遥控器（调用者请注意总套数，调用次数不要越界）
// data 索引数据首地址, data_len索引数据总长度
// cur_remote_handle 当前遥控器的句柄，next_remote_handle 返回下一套遥控码的句柄（用来获取下一套，不需要取下一套则传NULL）
// remote_id 第一套遥控码的id,不需要则传NULL，remote_data_offset 返回下一套遥控码在数据文件中的偏移量
// remote_data_len返回下一套遥控码数据长度
//
// 返回值 0 成功， -1 索引数据错误
int get_next_remote(const unsigned char *data, unsigned short data_len,
		unsigned short cur_remote_handle, unsigned short *next_remote_handle,
		unsigned short *remote_id, int *remote_data_offset,
		unsigned short *remote_data_len);

// 得到风扇遥控码信息
// data遥控器数据首地址, data_len遥控器数据总长度,
// power_flag返回1表示开关机同一个码，返回2表示开关机分开2个码
//
// speed_flag返回0表示无风速调节功能，返回1表示风速只有一个码，返回2表示风速+和风速-2个码，
// 返回3表示风速分低中高或者1,2,3之类的档位（码值不同），此时调用get_fan_pulse需要传入state参数
// 用来保存每次获取到风速相关的第几个码，用来下次获取下一个码。响应风速+顺序为（低->中->高或者1->2->3)
// 响应风速-顺序相反
//
// swing_flag返回0表示无摇头功能，返回1表示摇头只有一个码，返回2表示摇头和停止摇头2个码
//
// timer_flag返回0表示无定时功能，返回1表示定时只有一个码，返回2表示定时+和定时-2个码
// 返回3表示定时分定时1,3,6之类的档位（码值不同），此时调用get_fan_pulse需要传入state参数
// 用来保存每次获取到定时相关的第几个码，用来下次获取下一个码。响应定时+顺序为（1->2->3之类)
// 响应定时-顺序相反
//
// mode_flag返回0表示无模式功能，返回1表示模式只有一个码
//
// 返回0成功，-1 data指向的数据不合法
int get_fan_info(const unsigned char *data, unsigned short data_len,
		unsigned char *power_flag, unsigned char *speed_flag,
		unsigned char *swing_flag, unsigned char *timer_flag,
		unsigned char *mode_flag);

// 得到指定键的红外脉冲数据
// data遥控器数据首地址, data_len遥控器数据总长度,
//
// fid功能按鍵id，定义如下
// 电源 1,风速 2,摇头 3,定时 4,模式 5
//
// direct 1 向上方向比如风速+，开机，定时+， 0 向下风向比如风速-，关机，定时-
// get_fan_info接口flag=1时传0或者1任何值都可
// get_fan_info接口flag=2或者3时需要传入0或者1
//
// loop 是否循环，比如风速低中高之后下次调用是否返回低 0 不循环， 1 循环
// get_fan_info接口flag=1或者2时传0或者1任何值都可
// get_fan_info接口flag=3时根据具体应用需要传0或者1控制是否循环
//
// press_count该套遥控码当前是第几次按键（用来处理翻转码）， frequency返回频率比如38000，
// out 调用方准备好的返回高低电平缓冲区（单位：脉冲个数），
// out_max_num out允许存放的最大元素个数(out指向的可用内存空间/sizeof(unsigned short))，
// ret_num 编码完成后在out 内存空间中实际写了多少个unsigned short元素，
// frame_count 通过out返回的高低电平数组（一帧）需要重复的次数
// state用来处理flag=3的情况，
// 第一次调用state传0即可，后续每次调用传入上次调用返回的值即可,flag不为3可以传NULL
//
// 返回0成功，-1 data指向的数据不合法，-2 找不到fid传入的键对应的码值, -3 flag为3的时候state传递了NULL
int get_fan_pulse(const unsigned char *data, unsigned short data_len, int fid,
		unsigned char direct, unsigned char loop, unsigned char press_count,
		unsigned short *frequency, unsigned short *out,
		unsigned short out_max_num, unsigned short *ret_num,
		unsigned char *frame_count, unsigned char *state);

#ifdef __cplusplus
}
#endif

#endif // ZIP_AC_DEC_DIRECT_H_INCLUDED
